package cn.xawl.gulimall.product.service.impl;

import cn.xawl.common.constant.ProductConstant;
import cn.xawl.gulimall.product.dao.AttrAttrgroupRelationDao;
import cn.xawl.gulimall.product.entity.*;
import cn.xawl.gulimall.product.service.*;
import cn.xawl.gulimall.product.vo.AttrGroupWithAttrsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.xawl.common.utils.PageUtils;
import cn.xawl.common.utils.Query;

import cn.xawl.gulimall.product.dao.AttrGroupDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

@Transactional
@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {
    @Autowired
    private CategoryService categoryService;

    @Resource
    private AttrAttrgroupRelationDao aARelationDao;

    @Autowired
    private AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catalogId) {
        //select * from pms_attr_group where catalog_id = catalogId and (attr_group_id = key or attr_group_name like %key%)
        //创建查询条件
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        //判断当前参数中是否携带了查询字段key
        if (!StringUtils.isEmpty(key)) {
            wrapper.and((queryWrapper) -> {
                queryWrapper.eq("attr_group_id", key).or().like("attr_group_name", key);
            });
        }
        IPage<AttrGroupEntity> page;
        //判断当前的catalog是否为0
        if (catalogId != 0) {
            //不为0则根据查询关键字查询该分类id下的属性
            wrapper.eq("catalog_id", catalogId);
        } //为0则根据查询条件查询所有三级分类的属性
        page = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    @Override
    public List<Long> getCatalogPathById(Long catalogId) {
        //更具分类id查询出当前分类信息
        CategoryEntity category = categoryService.getById(catalogId);
        //定义一个list
        List<Long> catalogPath = new ArrayList<>();
        //判断当前catalogId是否有对应的分类信息，没有则直接返回空数组
        if (category != null) {
            getCatalogPath(category, catalogPath); //有则递归查找分类的父分类
        }
        Collections.reverse(catalogPath);
        return catalogPath;
    }

    @Override
    public List<AttrEntity> getAttrByGroup(Long attrgroupId) {
        //构建查询关联表的查询条件
        QueryWrapper<AttrAttrgroupRelationEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("attr_group_id", attrgroupId);
        //根据attrgroupId获取属性列表
        List<AttrAttrgroupRelationEntity> relationEntities = aARelationDao.selectList(wrapper);
        //定义返回的数据
        List<AttrEntity> data = new ArrayList<>();
        relationEntities.forEach((item) -> {//遍历关联表中的数据，根据attrId查询具体的AttrEntity添加到数据列表中
            AttrEntity attrEntity = attrService.getById(item.getAttrId());
            if (attrEntity != null) {
                data.add(attrEntity);
            }
        });
        return data;
    }

    @Override
    public void deleteRelations(List<AttrAttrgroupRelationEntity> relationEntities) {
        aARelationDao.deleteBatchRelation(relationEntities);
    }

    /**
     * 获取属性分组里面还没有关联的本分类里面的其他基本属性，方便添加新的关联
     *
     * @param params      分月参数以及模糊查询关键字
     * @param attrgroupId 分组属性id
     */
    @Override
    public PageUtils getAttrsByOtherRelation(Map<String, Object> params, Long attrgroupId) {
        //根据attrgroupId在关联表中查询出该分组下的所有关联信息

        //TODO 排除掉该分组已经关联的属性
        //我认为这里只需要查出所有关联表中的数据，抽取出属性id，在查属性的时候排除这些属性就可以查出 （该属性分组没有关联并且其他分组已经关联 ：就相当于关联表中的所有数据）  的属性信息
//        QueryWrapper<AttrAttrgroupRelationEntity> aARelationWrapper = new QueryWrapper<>();
//        aARelationWrapper.eq("attr_group_id", attrgroupId).ne("attr_group_id", attrgroupId);
//        aARelationWrapper.and((wrapper) -> {
//            wrapper.ne("attr_group_id", attrgroupId);
//        });

        List<AttrAttrgroupRelationEntity> relationEntities = aARelationDao.selectList(null);
        //遍历关联信息，获取该属性分组关联的所有属性id
        List<Long> attrIds = null;
        if (!CollectionUtils.isEmpty(relationEntities)) {
            //判断当前关联信息是个否为空
            attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        }

        //创建一个查询属性的wrapper
        QueryWrapper<AttrEntity> attrWrapper = new QueryWrapper<>();
        attrWrapper.notIn("attr_id", attrIds).and(wrapper -> wrapper.eq("attr_type", ProductConstant.AttrTypeEnum.ATTR_BASE_TYPE.getType()));
        //获取参数信息中的模糊查询关键字是否存在
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            //存在关键字，则添加模糊查询
            attrWrapper.and(wrapper -> wrapper.eq("attr_id", key).or().like("attr_name", key));
        }
        IPage<AttrEntity> page = attrService.getBaseMapper().selectPage(new Query<AttrEntity>().getPage(params), attrWrapper);

        return new PageUtils(page);
    }

    @Override
    public void addBatchRelation(List<AttrAttrgroupRelationEntity> list) {
        list.forEach((relationEntity) -> aARelationDao.insert(relationEntity));
    }

    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrsByCatalogId(Long catalogId) {

        //属性分组的表中根据分类id查询该分类的所有属性分组
        List<AttrGroupEntity> groupEntities = this.list(new QueryWrapper<AttrGroupEntity>().eq("catalog_id", catalogId));
        List<AttrGroupWithAttrsVo> data = new ArrayList<>();
        if (!CollectionUtils.isEmpty(groupEntities)) {
            //若查出的分组信息不为空,遍历每一个分组，根据分组的分子id从关联表中查询出该分组对应的所有属性id
            groupEntities.forEach(attrGroupEntity -> {
                AttrGroupWithAttrsVo attrGroupWithAttrsVo = new AttrGroupWithAttrsVo();
                //先将当前分组的属性赋值给视图对象
                BeanUtils.copyProperties(attrGroupEntity, attrGroupWithAttrsVo);
                //查询关联数据
                List<AttrAttrgroupRelationEntity> relationEntities = aARelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupEntity.getAttrGroupId()));

                //查询该分组对应的属性id
                List<Long> attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());

                //继续查询该分组下的所有属性
                List<AttrEntity> attrEntities = attrService.getBaseMapper().selectBatchIds(attrIds);
                //为试图对象添加 属性列表的值
                attrGroupWithAttrsVo.setAttrs(attrEntities);
                data.add(attrGroupWithAttrsVo);
            });
        }
        return data;
    }

    private void getCatalogPath(CategoryEntity categoryEntity, List<Long> catalogPath) {

        if (categoryEntity != null) {
            catalogPath.add(categoryEntity.getCatId());
            if (categoryEntity.getParentCid() != null) {
                getCatalogPath(categoryService.getById(categoryEntity.getParentCid()), catalogPath);
            }
        }
    }


}